package com.xiaoma.h5testdemo.common.helper

import android.annotation.SuppressLint
import android.app.Activity
import android.graphics.Rect
import android.view.View
import android.view.ViewTreeObserver.OnGlobalLayoutListener
import android.widget.FrameLayout
import androidx.fragment.app.Fragment
import com.xiaoma.lib.log.KLog
import java.lang.ref.WeakReference

class WebViewBugHelper private constructor(fragment: Fragment) {
    private val TAG = WebViewBugHelper::class.java.simpleName + "_XMTag"
    private var usableHeightPrevious = 0
    private var frameLayoutParams: FrameLayout.LayoutParams? = null
    private var contentHeight = 0
    private var isfirst = true
    private var statusBarHeight = 0
    private var mNeedMatchParent = false
    private var mFragmentWeakRef: WeakReference<Fragment>? = null
    private var mChildOfContentRef: WeakReference<View>? = null
    private val mGlobalLayoutListener = OnGlobalLayoutListener {
        try {
            if (isfirst) {
                mFragmentWeakRef?.get() ?: return@OnGlobalLayoutListener let {
                    KLog.e(TAG, "onGlobalLayout() " +
                            "mFragmentWeakReference: $mFragmentWeakRef " +
                            ",mFragmentWeakReference.get():${mFragmentWeakRef?.get()}")
                }
                val height = mChildOfContentRef?.get()?.height ?: 0
                if (height == 0) {
                    KLog.e(TAG, "onGlobalLayout() height = 0 !!!")
                    return@OnGlobalLayoutListener
                }
                contentHeight = height
                isfirst = false
                KLog.i(TAG, "onGlobalLayout() contentHeight:$contentHeight")
            }
            possiblyResizeChildOfContent()
        } catch (e: Exception) {
            KLog.e(TAG, "onGlobalLayout() XM_Exception: $e")
            e.printStackTrace()
        }
    }

    init {
        try {
            compatibleWebView(fragment)
            mFragmentWeakRef = WeakReference<Fragment>(fragment)
        } catch (e: Exception) {
            e.printStackTrace()
            KLog.e(TAG, "WebViewBugUtil() XM_Exception: $e")
        }
    }

    fun setNeedMatchParent(needMatchParent: Boolean) {
        mNeedMatchParent = needMatchParent
    }

    @SuppressLint("InternalInsetResource", "DiscouragedApi")
    private fun compatibleWebView(fragment: Fragment) {
        KLog.i(TAG, "compatibleWebView() ")
        val activity: Activity = fragment.requireActivity()
        //获取状态栏的高度
        val resourceId = activity.resources.getIdentifier("status_bar_height", "dimen", "android")
        statusBarHeight = activity.resources.getDimensionPixelSize(resourceId)
        val content = fragment.view
        mChildOfContentRef = WeakReference(content)
        //界面出现变动都会调用这个监听事件
        content?.viewTreeObserver?.addOnGlobalLayoutListener(mGlobalLayoutListener)
        frameLayoutParams = content?.layoutParams as? FrameLayout.LayoutParams
    }

    //重新调整跟布局的高度
    private fun possiblyResizeChildOfContent() {
        mFragmentWeakRef?.get() ?: return let {
            KLog.e(TAG, "possiblyResizeChildOfContent() " +
                    "mFragmentWeakReference: $mFragmentWeakRef " +
                    ",mFragmentWeakReference.get():${mFragmentWeakRef?.get()}")
        }
        val childOfContent = mChildOfContentRef?.get() ?: return let {
            KLog.e(TAG, "possiblyResizeChildOfContent() " +
                    "mChildOfContentRef: $mChildOfContentRef " +
                    ",mChildOfContentRef.get():${mChildOfContentRef?.get()}")
        }
        val usableHeightNow = computeUsableHeight(childOfContent)
        //当前可见高度和上一次可见高度不一致 布局变动
        if (usableHeightNow != usableHeightPrevious) {
            //int usableHeightSansKeyboard2 = mChildOfContent.getHeight();//兼容华为等机型
            val usableHeightSansKeyboard = childOfContent.rootView.height
            val heightDifference = usableHeightSansKeyboard - usableHeightNow
            val step: Int
            if (heightDifference > usableHeightSansKeyboard / 4) {
                step = 1
                // keyboard probably just became visible
                //frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
                frameLayoutParams!!.height = usableHeightSansKeyboard - heightDifference + statusBarHeight
            } else {
                if (mNeedMatchParent) {
                    step = 2
                    frameLayoutParams!!.height = FrameLayout.LayoutParams.MATCH_PARENT
                } else {
                    step = 3
                    frameLayoutParams!!.height = contentHeight
                }
            }
            KLog.i(TAG, "possiblyResizeChildOfContent() " +
                    "mNeedMatchParent:" + mNeedMatchParent +
                    ",step: " + step
            )
            childOfContent.requestLayout()
            usableHeightPrevious = usableHeightNow
        }
    }

    /**
     * 计算mChildOfContent可见高度     ** @return
     */
    private fun computeUsableHeight(childOfContent: View): Int {
        val r = Rect()
        childOfContent.getWindowVisibleDisplayFrame(r)
        return r.bottom - r.top
    }

    fun release() {
        try {
            KLog.i(TAG, "release() ")
            mChildOfContentRef?.get()?.viewTreeObserver?.removeOnGlobalLayoutListener(mGlobalLayoutListener)
            mFragmentWeakRef?.clear()
            mChildOfContentRef?.clear()
        } catch (e: Exception) {
            e.printStackTrace()
            KLog.e(TAG, "release() XM_Exception: $e")
        }
    }

    companion object {
        fun assistActivity(fragment: Fragment): WebViewBugHelper {
            return WebViewBugHelper(fragment)
        }
    }
}